//==============================================================================
//
//              DBool - the boolean class in the ofc-library
//
//               Copyright (C) 2003  Dick van Oudheusden
//  
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2004-02-20 20:16:33 $ $Revision: 1.6 $
//
//==============================================================================

#include "ofc/DBool.h"

#include <string.h>
#include <ctype.h>


#if _INTERFACE_

#include "ofc/config.h"

#include "ofc/DComparable.h"
#include "ofc/DTextable.h"
#include "ofc/DDatable.h"
#include "ofc/DParsable.h"

#include "ofc/DText.h"
#include "ofc/DData.h"

// The Bool class implements a number of methods for storing and manipulating booleans.

@interface DBool : Object <DComparable,DTextable,DDatable,DParsable>
{
@private
  BOOL         _bool;    // the boolean state
}

#endif



@implementation DBool


//// Constructors

//
// Initialise to false
//
// @return the object
//

- (DBool *) init
{
  [super init];

  _bool = NO;
  
  return self;
}

//
// Initialise to a state
//
// @param state    the state (YES,NO)
//
// @return the object
//

- (DBool *) init :(BOOL) state
{
  [self init];

  _bool = state;

  return self;
}


//// Member methods

//
// Get the boolean state
//
// @return the state
//

- (BOOL) get
{
  return _bool;
}

//
// Set the boolean state
//
// @param state    the state
//
// @return the object
//

- (DBool *) set :(BOOL) state
{
  _bool = state;

  return self;
}


//// Comparable protocol

//
// Compare two bool objects
//
// @param other    the object to compare with
//
// @return the result of the comparison (-1,0,1)
//

- (int) compare :(DBool *) other
{
  if (self != other)
  {
    BOOL state = [other get];
    
    if (_bool == state)
    {
      return 0;
    }
    else if (_bool)
    {
      return 1;
    }
    else
    {
      return -1;
    }
  }
  else
  {
    return 0;
  }
}
 

//// Parsable protocol

//
// Parse a string for a boolean state (the string should contain: true/false,
// yes/no, y/n, 1/0, t/f (case insensitive))
//
// @param cstr     the string to be parsed (moved to the first no-parsable char)
//
// @return the result (0, ENODATA)
//

- (int) fromString :(char **) cstr
{
  int   result = 0;
  char *pntr   = *cstr;

  if (strncasecmp(pntr, "true", 4) == 0)
  {
    _bool = YES;
    pntr += 4;
  }
  else if (strncasecmp(pntr, "false", 5) == 0)
  {
    _bool = NO;
    pntr += 5;
  }
  else if (strncasecmp(pntr, "yes", 3) == 0)
  {
    _bool = YES;
    pntr += 3;
  }
  else if (strncasecmp(pntr, "no", 2) == 0)
  {
    _bool = NO;
    pntr += 2;
  }
  else
  {
    char ch = tolower(*pntr);
    
    if ((ch == '1') || (ch == 'y') || (ch == 't'))
    {
      _bool = YES;
      pntr++;
    }
    else if ((ch == '0') || (ch == 'n') || (ch == 'f'))
    {
      _bool = NO;
      pntr++;
    }
    else
    {
      result = ENODATA;
    }
  }
  
  *cstr = pntr;

  return result;
}


//// Textable protocol

//
// Return a text string 
//
// @return a (new) text string with the boolean state (YES/NO)
//

- (DText *) toText
{
  DText *text = [DText alloc];
  
  return [text init :(_bool ? "YES" : "NO")];
}
    

//// Datable protocol

//
// Return a data string
//
// @return a (new) data string
//

- (DData *) toData
{
  return [[DData alloc] init :(unsigned char *)&_bool :sizeof(_bool)];
}

@end

/*==========================================================================*/

